package com.dlc.hardwareprotocol.serialport;


import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.serialport.SerialPort;

import com.dlc.hardwareprotocol.Protocol;
import com.dlc.hardwareprotocol.serialport.command.RecvCommand;
import com.dlc.hardwareprotocol.serialport.command.recv.RecvBA;
import com.dlc.hardwareprotocol.serialport.command.recv.RecvBase;
import com.dlc.hardwareprotocol.serialport.command.send.SendBA;
import com.dlc.hardwareprotocol.serialport.utils.LogPlus;
import com.licheedev.serialworker.core.Callback;

import org.jetbrains.annotations.NotNull;

import java.io.File;

import io.reactivex.Observable;

public class MainSerialManager {
    private final HandlerThread mDispatchThread;
    private final MainSerialWorker mSerialWorker;

    private MainSerialWorker.ReceiveCallback receiveCallback;

    /*private*/
    public MainSerialManager() {
        if (new File("/system/bin/su").exists()) {
            SerialPort.setSuPath("/system/bin/su");
        } else if (new File("/system/xbin/su").exists()) {
            SerialPort.setSuPath("/system/xbin/su");
        }
        LogPlus.setSaveLogToFile(true, "w");//保存日志到本地
        mDispatchThread = new HandlerThread("serial-dispatch-thread_" + System.currentTimeMillis());
        mDispatchThread.start();
        Handler mDispatchThreadHandler = new Handler(mDispatchThread.getLooper());
        mSerialWorker = new MainSerialWorker(mDispatchThreadHandler);
        mSerialWorker.setParams(8, 0, 1); // 8数据位，无校验，1停止位
        // 设置超时
        mSerialWorker.setTimeout(Protocol.RECEIVE_TIME_OUT);
        // 开启打印日志
        mSerialWorker.enableLog(false, false);
        mSerialWorker.setReceiveCallback(recvCommand -> {
            if (recvCommand instanceof RecvBase) {

            }
            if (receiveCallback != null) {
                receiveCallback.onReceive(recvCommand);
            }
        });
    }

    public void initDevice(String devicePath, int baudRate, SerialOpenCallBack callBack) {
        mSerialWorker.setDevice(devicePath, baudRate); // 串口地址，波特率
        mSerialWorker.openSerial(new Callback<SerialPort>() {
            @Override
            public void onSuccess(SerialPort serialPort) {
                callBack.onSuccess();

            }

            @Override
            public void onFailure(Throwable tr) {
                callBack.onFailure();
            }
        });
    }


    public boolean isSerialPortOpened() {
        return mSerialWorker.isSerialOpened();
    }


    public void sendXX(byte[] data) {
        mSerialWorker.sendBytes(data, null);
    }

    /**
     * 查询控制板工作状态数据 BA
     */
    public void sendBA() {
        SendBA send = new SendBA();
        mSerialWorker.sendOnly(send, null);
    }

    @NotNull
    public Observable<RecvBA> sendA8(int flowNo, int cargoNumberType, int actionCargoRowNumberOrNo1, @NotNull Object actionCargoColumnNumber1, @NotNull Object actionCargoRowNumberOrNo2, @NotNull Object actionCargoColumnNumber2, @NotNull Object actionCargoRowNumberOrNo3, @NotNull Object actionCargoColumnNumber3, @NotNull Object actionCargoRowNumberOrNo4, @NotNull Object actionCargoColumnNumber4, @NotNull Object actionCargoRowNumberOrNo5, @NotNull Object actionCargoColumnNumber5, @NotNull Object maxActionTime, @NotNull Object pickTimeOut, @NotNull Object theftBaffleTimeout) {
        return null;
    }


    public interface SerialOpenCallBack {
        void onSuccess();

        void onFailure();
    }

    public interface ReceiveCallBack {
        void onReceive(RecvCommand recvCommand);

    }

    public synchronized void release() {
        mSerialWorker.release();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            mDispatchThread.quitSafely();
        } else {
            mDispatchThread.quit();
        }
    }

    public MainSerialWorker.ReceiveCallback getReceiveCallback() {
        return receiveCallback;
    }

    public void setReceiveCallback(MainSerialWorker.ReceiveCallback receiveCallback) {
        this.receiveCallback = receiveCallback;
    }

    public void close() {
        mSerialWorker.closeSerial();
    }
}
